package com.github.bryx.workflow.referenceobject;

import com.github.bryx.workflow.util.CollectionsUtil;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 *
 * 引用对象ids组装器
 * @Author jameswu
 * @Date 2021/7/21
 **/
public class ReferenceObjectBuilder {
    public static class InnerBuilder{
        private InnerBuilder(){

        }
        private Class type;
        private Collection ids;
        private ReferenceObjectBuilder builder;
        private InnerBuilder(ReferenceObjectBuilder builder, Collection ids){
            this.builder = builder;
            this.ids = ids;
        }

        /**
         * 批量添加ids
         * @param ids
         */
        public InnerBuilder addAll(Collection ids){
            if (CollectionsUtil.empty(ids)){
                return this;
            }
            this.ids.addAll(ids);
            return this;
        }

        /**
         * 添加单个id
         * @param id
         */
        public InnerBuilder add(Object id){
            if (id == null){
                return this;
            }
            this.ids.add(id);
            return this;
        }

        /**
         * 结束为类型添加ids
         */
        public ReferenceObjectBuilder and(){
            return this.builder;
        }

        public Map<Class, Collection> build(){

            Set<Class> keys = new HashSet<>(this.builder.referenceObjectIds.keySet());
            for(Class key : keys){
                if (CollectionsUtil.empty(this.builder.referenceObjectIds.get(key))){
                    this.builder.referenceObjectIds.remove(key);
                }else{
                    Set<Object> ids = Sets.newHashSet();
                    ids.addAll(this.builder.referenceObjectIds.get(key));
                    this.builder.referenceObjectIds.put(key, ids);
                }
            }
            return this.builder.referenceObjectIds;
        }
    }

    Map<Class, Collection> referenceObjectIds;

    private ReferenceObjectBuilder(){
        referenceObjectIds = Maps.newHashMap();
    }

    public static ReferenceObjectBuilder builder(){
        return new ReferenceObjectBuilder();
    }

    public InnerBuilder type(Class clazz){
        Set set = Sets.newHashSet();
        referenceObjectIds.put(clazz, set);
        return new InnerBuilder(this, set);
    }
}
